package com.hushow.jodconverter.demo.controller;

import lombok.extern.slf4j.Slf4j;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.document.DocumentFormat;
import org.jodconverter.core.job.TargetDocumentSpecsFromFile;
import org.jodconverter.core.office.OfficeException;
import org.jodconverter.core.util.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebServlet;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

@RestController
@RequestMapping("/demo/")
@Slf4j
public class JodconverterDemoController {

    @Resource
    private DocumentConverter converter;

    @Resource
    ServletContext servletContext;

    @PostMapping("/converter")
    Object convert(
            @RequestParam("inputFile") final MultipartFile inputFile,
            @RequestParam(name = "outputFormat", required = false) final String outputFormat) {


        File tempDir = WebUtils.getTempDir(servletContext);

        if (inputFile.isEmpty()) {
            return "Please select a file to upload";
        }

        if (!StringUtils.hasText(outputFormat)) {
            return "Please select an output format.";
        }
        // Here, we could have a dedicated service that would convert document
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {

            final DocumentFormat targetFormat =
                    DefaultDocumentFormatRegistry.getFormatByExtension(outputFormat);
            Assert.notNull(targetFormat, "targetFormat must not be null");


            converter.convert(inputFile.getInputStream()).to(baos).as(targetFormat).execute();

            final HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(targetFormat.getMediaType()));
            headers.add(
                    "Content-Disposition",
                    "attachment; filename="
                            + FileUtils.getBaseName(inputFile.getOriginalFilename())
                            + "."
                            + targetFormat.getExtension());
            return new ResponseEntity<>(baos.toByteArray(), headers, HttpStatus.OK);

        } catch (OfficeException | IOException e) {
            log.error("Could not convert the file"+e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }



    @PostMapping("/converter2")
    String convert2(
            @RequestParam(value = "inputFile", required = true) final MultipartFile inputFile,
            @RequestParam(name = "outputFormat", required = true) final String fileName,
            @RequestParam(name = "outputFormat", required = false) final String outputFormat) {
        try{

            File tempDir = WebUtils.getTempDir(servletContext);

            if (inputFile.isEmpty()) {
                return "Please select a file to upload";
            }

            if (!StringUtils.hasText(outputFormat)) {
                return "Please select an output format.";
            }

            DocumentFormat targetFormat =
                    DefaultDocumentFormatRegistry.getFormatByExtension(outputFormat);
            Assert.notNull(targetFormat, "targetFormat must not be null");
            TargetDocumentSpecsFromFile targetDocumentSpecsFromFile;
            String filePath = tempDir.getAbsolutePath()+ File.separator+fileName;
            log.info("filePath:{}", filePath);
            converter.convert(inputFile.getInputStream()).to(new File(filePath)).as(targetFormat).execute();
            return "ok";

        } catch (OfficeException | IOException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }
}
